package latexExport;

import java.awt.FileDialog;
import java.io.*;

import javax.swing.JFrame;

import master.*;

public class QuantumRegisterLaTeXWriter extends BufferedWriter{
	public QuantumRegisterLaTeXWriter(Writer w) {
		super(w);
	}
	public void writeRegister(QuantumRegister r) throws IOException{
		write("\\subsection{eigenstates}");
		newLine();
		write("\\begin{tabular}{| l c |}");
		newLine();
		
		
		
		for(int i = 0 ; i < r.getDimension() ; i++){
			write("\t $ | " +r.bitString(i)+ " \\rangle $ & ");
			write(" $ "+r.getCoefficient(i) + " $ \\\\"); newLine();
		}
		
		newLine();
		write("\\end{tabular}"); newLine();
	}
	public void writeInline(QuantumRegister r) throws IOException{
		int firstNonZero = 0;
		while(firstNonZero<r.getDimension()&&r.getCoefficient(firstNonZero).isZero())
			firstNonZero++;
		if(firstNonZero <r.getDimension()){
			write("$");
			for(int i = 0 ; i < r.getDimension() ; i++){
				if(!r.getCoefficient(i).isZero()){
					if(i>firstNonZero) write(" + ");
					write("("+r.getCoefficient(i)+") |" + r.bitString(i) + "\\rangle");
				}
			}
		}
		write("$");
	}
	public static void main(String [] args)throws IOException{
		JFrame m = new JFrame();
		m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		FileDialog g = new FileDialog(m);
		g.setVisible(true);
		g.setMode(g.SAVE);
		String t = g.getDirectory() + g.getFile();
		g.setVisible(false);
		File f = new File(t);
		FileWriter w = new FileWriter(f);
		QuantumRegisterLaTeXWriter r = new QuantumRegisterLaTeXWriter(w);
		r.write("\\documentstyle{report}"); r.newLine();
		r.write("\\begin{document}"); r.newLine();
		QuantumRegister qr = new QuantumRegister(3);
		
		r.write(
				"\\section{Quantum Entanglement of two Eigenstates}");
		r.newLine();
		r.write(
				"Suppose we begin a superposition of the two eigenstates $|000 \\rangle$ and "+
				"$ |011\\rangle $"
				);
		
		qr.setCoefficient(
				ComplexNumber.expi(0.5f, (float)( Math.random()*Math.PI*2 ))
				, 0);
		qr.setCoefficient(
				ComplexNumber.expi(0.5f, (float)( Math.random()*Math.PI*2 ))
				, 3);
		QuantumRegister before = qr.copy();
		r.writeRegister(qr);
		qr.collapseToEigenstate();
		r.write("\\section{After eigenstate collapse}");
		r.writeRegister(qr);
		
		r.write(
				"\\\\\\\\We see that, in fact, a measurement of the value of one qubit has had "+
				"an impact on the value of the other, this is because the two qubits are ``"+
				"entangled''."
				);
		r.newLine();
		r.write("\\\\Now, to assure ourselves of the random nature of the entanglement, let us "+
				"Once again prepare the register in the previously stated state: ");
		r.writeInline(before);
		
		int measure = 10000;
		
		r.write("\\\\If we measure this system $" +measure+"$ times under identical conditions,"+
				" we find that:");
		
		int[] results = before.nMeasure(measure);
		
		int [] res = new int[before.getDimension()];
		for(int i = 0 ; i < before.getDimension();i++)
			res[i] = 0;
		
		for(int i = 0 ; i < measure ; i++)
			res[results[i]]++;
		
		r.newLine();
		r.write("\\begin{tabular}{ l l }");
		r.newLine();
		r.write("\t eigenstate & measured \\\\");
		r.newLine();
		for(int i = 0 ; i < before.getDimension() ;i++){
			r.write("\t $|"+before.bitString(i)+"\\rangle$ & $" +res[i]+ "$ \\\\");
			r.newLine();
		}
		r.write("\\end{tabular}");
		r.newLine();
		System.out.println(before);
		r.write("\\end{document}"); r.newLine();
		r.close();
		w.close();
		
	}
}
